/*
 * FileSystem.cpp
 *
 *  Created on: Apr 16, 2012
 *      Author: jaap
 */

#include "FileSystem.h"

FileSystem::FileSystem(const char * device) {
	this->device = new Device(device);
	SOFT = new list<OpenFile*> ();
	AIT = new map<int, Inode*> ();

	Block* super = this->device->getBlock(1);

	int amountInodeBlocks = super->getAmountOfInodeBlocks();
	int amountBlocks = super->getAmountOfBlocks();
	cout << "Amount of blocks in i-list: " << amountInodeBlocks << endl;
	cout << "Amount of blocks in total: " << amountBlocks << endl;
	cout << "Free adresses: " << getshort(super->getBytes(), 6) << endl;
	Inode* root = getInodeByNumber(4);
	cout << itoo(4) << "-> " << root->getNumber() << "-" << root->getFilesize() << "-"
			<< root->getLinkcount() << endl;
	root = getInodeByNumber(7);
	cout << itoo(7) << "-> " << root->getNumber() << "-" << root->getFilesize() << "-"
			<< root->getLinkcount() << endl;
	cout <<sizeof(short)<<", "<<sizeof(int)<<", "<<sizeof(long)<<", ";
}

FileSystem::~FileSystem() {
	for (list<OpenFile*>::iterator iter = SOFT->begin(); iter != SOFT->end(); ++iter) {
		delete *iter;
	}
	for (map<int, Inode*>::iterator iter = AIT->begin(); iter != AIT->end(); ++iter) {
		delete &iter;
	}
	delete device;
	delete SOFT;
	delete AIT;
}

Inode * FileSystem::findInode(const char * absolute_path) {
	return 0;
}

Inode * FileSystem::findFile(Inode * dirptr, const char * filename) {
	OpenDirectory* dir = new OpenDirectory(dirptr, "");
	Inode * file = dir->find(filename);
	delete dir;
	return file;
}

OpenFile * FileSystem::open(const char * path) {
	return 0;
}

int FileSystem::read(OpenFile * fileptr, char buffer[], int count) {
	assert(fileptr != 0);
	SOFT->push_front(fileptr);
	return fileptr->read(buffer, count);
}

int FileSystem::lseek(OpenFile * fileptr, long offset, int whence) {
	return 0;
}

void FileSystem::close(OpenFile * fileptr) {

}

void FileSystem::releaseInode(Inode * ip) {
	AIT->erase(ip->getNumber());
}

map<int, Inode*>* FileSystem::getAIT() {
	return AIT;
}

list<OpenFile*>* FileSystem::getSOFT() {
	return SOFT;
}

Inode* FileSystem::getInodeByNumber(int number) {
	Block  * block = device->getBlock(itod(number));

	cout << "FILESIZE = " << getlong( block->getBytes(itoo(number) * INSIZ, INSIZ), 8) << endl;

	Inode* inode = new Inode(number,
			block->getBytes(itoo(number) * INSIZ, INSIZ));
	return inode;
}
